Use eglGetPlatformDisplay{,EXT} if available
authorAdam Jackson <ajax@redhat.com>
Mon, 10 Oct 2016 18:12:40 +0000 (14:12 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Mon, 10 Oct 2016 18:17:09 +0000 (14:17 -0400)
Calling eglGetDisplay forces libEGL to guess what kind of pointer you
passed it. Different EGL libraries will do different things here, and in
particular glvnd will do something different than Mesa. Since we do have
an API that allows us to explicitly type the display, use it.

The explicit call to eglGetProcAddress is working around a bug in
libepoxy 1.3, which does not understand the EGL concept of client
extensions. Since it does not, the normal epoxy resolver for
eglGetPlatformDisplayEXT would not find any provider for that entry
point, and crash when you attempted to call it.

Signed-off-by: Adam Jackson <ajax@redhat.com>
https://bugzilla.gnome.org/show_bug.cgi?id=772415

gdk/wayland/gdkglcontext-wayland.c
gtk/inspector/general.c

index ae1354ef70fef884eb28f2cc60414be53ec3d240..657368860f592373f78c9ff43de4795f8d0276ce 100644 (file)
@@ -274,6 +274,40 @@ gdk_wayland_gl_context_init (GdkWaylandGLContext *self)
 {
 }
 
+static EGLDisplay
+gdk_wayland_get_display (GdkWaylandDisplay *display_wayland)
+{
+  EGLDisplay dpy = NULL;
+
+  if (epoxy_has_egl_extension (NULL, "EGL_KHR_platform_base"))
+    {
+      PFNEGLGETPLATFORMDISPLAYPROC getPlatformDisplay =
+       (void *) eglGetProcAddress ("eglGetPlatformDisplay");
+
+      if (getPlatformDisplay)
+       dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT,
+                                 display_wayland->wl_display,
+                                 NULL);
+      if (dpy)
+       return dpy;
+    }
+
+  if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
+    {
+      PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay =
+       (void *) eglGetProcAddress ("eglGetPlatformDisplayEXT");
+
+      if (getPlatformDisplay)
+       dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT,
+                                 display_wayland->wl_display,
+                                 NULL);
+      if (dpy)
+       return dpy;
+    }
+
+  return eglGetDisplay ((EGLNativeDisplayType) display_wayland->wl_display);
+}
+
 gboolean
 gdk_wayland_display_init_gl (GdkDisplay *display)
 {
@@ -284,7 +318,8 @@ gdk_wayland_display_init_gl (GdkDisplay *display)
   if (display_wayland->have_egl)
     return TRUE;
 
-  dpy = eglGetDisplay ((EGLNativeDisplayType)display_wayland->wl_display);
+  dpy = gdk_wayland_get_display (display_wayland);
+
   if (dpy == NULL)
     return FALSE;
 
index 77d0a767f10d57b8493a1e52da73c99c8ae9c3db..f7f82235ca299e02c0c8f54b4c454db5c6f0d9d5 100644 (file)
@@ -214,6 +214,40 @@ append_egl_extension_row (GtkInspectorGeneral *gen,
 {
   add_check_row (gen, GTK_LIST_BOX (gen->priv->gl_box), ext, epoxy_has_egl_extension (dpy, ext), 0);
 }
+
+static EGLDisplay
+wayland_get_display (GdkWaylandDisplay *display_wayland)
+{
+  EGLDisplay dpy = NULL;
+
+  if (epoxy_has_egl_extension (NULL, "EGL_KHR_platform_base"))
+    {
+      PFNEGLGETPLATFORMDISPLAYPROC getPlatformDisplay =
+        (void *) eglGetProcAddress ("eglGetPlatformDisplay");
+
+      if (getPlatformDisplay)
+        dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT,
+                                  display_wayland->wl_display,
+                                  NULL);
+      if (dpy)
+        return dpy;
+    }
+
+  if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
+    {
+      PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay =
+        (void *) eglGetProcAddress ("eglGetPlatformDisplayEXT");
+
+      if (getPlatformDisplay)
+        dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT,
+                                  display_wayland->wl_display,
+                                  NULL);
+      if (dpy)
+        return dpy;
+    }
+
+  return eglGetDisplay ((EGLNativeDisplayType) display_wayland->wl_display);
+}
 #endif
 
 
@@ -254,7 +288,7 @@ init_gl (GtkInspectorGeneral *gen)
       EGLint major, minor;
       gchar *version;
 
-      dpy = eglGetDisplay ((EGLNativeDisplayType)gdk_wayland_display_get_wl_display (display));
+      dpy = wayland_get_display (gdk_wayland_display_get_wl_display (display));
 
       if (!eglInitialize (dpy, &major, &minor))
         return;